/* 
 * Enterprise Library Extensions - DI + ORM.
 * Copyright (C) 2006
 *
 * GNU General Public License
 *
 * This program is free software; you can redistribute 
 * it and/or modify it under the terms of the GNU General Public License 
 * as published by the Free Software Foundation; either version 2 of the 
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
 * See the GNU General Public License for more details.
 */
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.Practices.EnterpriseLibrary.Data;
using ELE.EnterpriseLibrary.Data;

namespace ELE.EnterpriseLibrary.Test
{
  [TestClass]
  public class ORDataTestFixture : BaseFixture
  {
    private Employee BuildEmployee()
    {
      Employee upEmployee = new Employee();
      upEmployee.Id = 101;
      upEmployee.Name = "Pedro Perez Delgado";
      upEmployee.BirthDate = new DateTime(1970, 10, 21);
      upEmployee.Address = new Address();
      upEmployee.Address.Id = 101;
      upEmployee.Address.StreetName = "La Calle del Conde";
      upEmployee.Address.UnitNumber = "692";
      upEmployee.Address.ZipCode = "21321";
      this.AddAliasToEmployee(upEmployee, 102, "EL CONDE");
      this.AddAliasToEmployee(upEmployee, 103, "CONDORITO");
      this.AddEquipmentToEmployee(upEmployee, 103, "0029903993");
      return upEmployee;
    }
    private void AddAliasToEmployee(Employee employee, int aliasId, string aliasValue)
    {
      Alias alias = new Alias();
      alias.Id = aliasId;
      alias.Value = aliasValue;
      alias.EmployeeId = employee.Id;

      if(employee.Aliases == null)
      {
        employee.Aliases = new List<Alias>();
      }
      employee.Aliases.Add(alias);
    }
    private void AddEquipmentToEmployee(Employee employee, int eqId, string eqSerialNumber)
    {
      Equipment equip = new Equipment();
      equip.Id = eqId;
      equip.SerialNumber = eqSerialNumber;
      if(employee.Equipment == null)
      {
        employee.Equipment = new List<Equipment>();
      }
      employee.Equipment.Add(equip);
    }
    /// <summary>
    /// This test method is used to test the functionality of the query runner built into an <see cref="ObjectStorage"/> created by using
    /// the default storage from the <see cref="ObjectStorageFactory"/>.
    /// </summary>
    [TestMethod]
    public void TestObjectStorage()
    {
      //System.Reflection.MethodInfo staticMethod = (typeof(DatabaseFactory)).GetMethod("CreateDatabase", new Type[0] );
      //Database d = (Database) staticMethod.Invoke(null, null);
      Database db = DatabaseFactory.CreateDatabase();
      Employee inputObject = new Employee();
      inputObject.Id = 100;
      ObjectStorage store = ObjectStorageFactory.CreateStorage();
      IObjectQueryRunner storageQueryRunner = store.GetQueryRunner();

      IList storedObjects = storageQueryRunner.ExecuteQueryByName(db, "GetEmployeeById", inputObject);
      IList lightStoredObjects = storageQueryRunner.ExecuteQueryByNameLightweight(db, "GetEmployeeById", inputObject);
      Employee storedEmployee = (Employee)storageQueryRunner.QueryObjectByPrimaryKey(db, "Employee", inputObject.Id);
      Employee lightStoredEmployee = (Employee)storageQueryRunner.QueryObjectByPrimaryKeyLightweight(db, "Employee", inputObject.Id);

      Assert.IsNotNull(storedEmployee, "Employee must not be null, make sure theres is an employee with id = 0");

      Employee upEmployee = this.BuildEmployee();
      int addedRows = storageQueryRunner.PersistObject(db, "Employee", upEmployee);
      Console.WriteLine(string.Format("Added {0} rows", addedRows));
      Assert.IsTrue(addedRows > 0, "Did not add the rows to the database");

      this.AddEquipmentToEmployee(upEmployee, 4, "0334442332");

      int updatedRows = storageQueryRunner.PersistObject(db, "Employee", upEmployee);
      Console.WriteLine(string.Format("Updated {0} rows", updatedRows));
      Assert.IsTrue(updatedRows > 0, "Did not add the rows to the database");

      int deletedRows = storageQueryRunner.RemoveObject(db, "Employee", upEmployee);
      Console.WriteLine(string.Format("Deleted {0} rows", deletedRows));
      Assert.IsTrue(deletedRows > 0, "Did not add the rows to the database");

      DataSet spResults = storageQueryRunner.ExecuteDatasetStoredProcedureByName(db, "GetEmployeeNameSP", storedEmployee);
      Assert.IsNotNull(spResults, "Failed to get results from stored procedure");
    }
    /// <summary>
    /// This method is used for testing functionality in the <see cref="ObjectQueryRunner"/> created using its default constructor.
    /// </summary>
    [TestMethod]
    public void TestQueryRunner()
    {
      Database db = DatabaseFactory.CreateDatabase();
      Employee inputObject = new Employee();
      inputObject.Id = 100;

      IObjectQueryRunner runner = new ObjectQueryRunner(@"C:\CodePlex\Workspace\ELE\ELE.EnterpriseLibrary\ELE.EnterpriseLibrary.UnitTest\ORMapping.config");


      DataSet ds = runner.ExecuteDatasetQueryByName(db, "GetEmployeeById", inputObject);
      Assert.IsNotNull(ds, "Dataset is null");

      IList objects = runner.ExecuteQueryByName(db, "GetEmployeeById", inputObject);
      IList lightObjects = runner.ExecuteQueryByNameLightweight(db, "GetEmployeeById", inputObject);
      Employee employee = (Employee)runner.QueryObjectByPrimaryKey(db, "Employee", inputObject.Id);
      Employee lightEmployee = (Employee)runner.QueryObjectByPrimaryKeyLightweight(db, "Employee", inputObject.Id);

      Assert.IsNotNull(employee, "Employee must not be null, make sure theres is an employee with id = 0");

      Employee upEmployee = this.BuildEmployee();
      int addedRows = runner.PersistObject(db, "Employee", upEmployee);
      Console.WriteLine(string.Format("Added {0} rows", addedRows));
      Assert.IsTrue(addedRows > 0, "Did not add the rows to the database");

      this.AddEquipmentToEmployee(upEmployee, 104, "0334442332");

      int updatedRows = runner.PersistObject(db, "Employee", upEmployee);
      Console.WriteLine(string.Format("Updated {0} rows", updatedRows));
      Assert.IsTrue(updatedRows > 0, "Did not add the rows to the database");

      int deletedRows = runner.RemoveObject(db, "Employee", upEmployee);
      Console.WriteLine(string.Format("Deleted {0} rows", deletedRows));
      Assert.IsTrue(deletedRows > 0, "Did not add the rows to the database");

      DataSet spResults = runner.ExecuteDatasetStoredProcedureByName(db, "GetEmployeeNameSP", employee);
      Assert.IsNotNull(spResults, "Failed to get results from stored procedure");
    }
  }
}
